From 5718fab870ddbee45cdc93bdedbb46b7dc76d6a5 Mon Sep 17 00:00:00 2001 From: "kaf24@labyrinth.cl.cam.ac.uk" Date: Mon, 3 Feb 2003 16:33:53 +0000 Subject: [PATCH] bitkeeper revision 1.22.1.1 (3e3e99f1o3TNE3GpOg3lVm9IdI7Z7Q) Many files: We now have a shared read-only machine->physical mapping table at start of hypervisor virtual address region. --- xen-2.4.16/arch/i386/Rules.mk | 2 +- xen-2.4.16/arch/i386/boot/boot.S | 10 ++++--- xen-2.4.16/arch/i386/mm.c | 8 +++++- xen-2.4.16/arch/i386/xeno.lds | 2 +- xen-2.4.16/common/domain.c | 12 ++++++--- xen-2.4.16/common/memory.c | 16 +++++++---- xen-2.4.16/include/asm-i386/page.h | 14 ++++++++-- .../include/hypervisor-ifs/hypervisor-if.h | 6 ++++- xen-2.4.16/include/xeno/config.h | 27 ++++++++++++++++--- 9 files changed, 76 insertions(+), 21 deletions(-) diff --git a/xen-2.4.16/arch/i386/Rules.mk b/xen-2.4.16/arch/i386/Rules.mk index 6923537ff3..323730c8ee 100644 --- a/xen-2.4.16/arch/i386/Rules.mk +++ b/xen-2.4.16/arch/i386/Rules.mk @@ -4,7 +4,7 @@ CC := gcc LD := ld # Linker should relocate monitor to this address -MONITOR_BASE := 0xFC100000 +MONITOR_BASE := 0xFC500000 # Bootloader should load monitor to this real address LOAD_BASE := 0x00100000 CFLAGS := -fno-builtin -O3 -Wall -DMONITOR_BASE=$(MONITOR_BASE) diff --git a/xen-2.4.16/arch/i386/boot/boot.S b/xen-2.4.16/arch/i386/boot/boot.S index bd62d8ffba..091b760576 100644 --- a/xen-2.4.16/arch/i386/boot/boot.S +++ b/xen-2.4.16/arch/i386/boot/boot.S @@ -216,13 +216,15 @@ nopaging_gdt_descr: .long SYMBOL_NAME(gdt_table)-__PAGE_OFFSET ALIGN +/* NB. Rings != 0 get access up to 0xFC400000. This allows access to the */ +/* machine->physical mapping table. Ring 0 can access all memory. */ ENTRY(gdt_table) .quad 0x0000000000000000 /* NULL descriptor */ .quad 0x0000000000000000 /* not used */ - .quad 0x00cfba000000bfff /* 0x11 ring 1 3.95GB code at 0x0 */ - .quad 0x00cfb2000000bfff /* 0x19 ring 1 3.95GB data at 0x0 */ - .quad 0x00cffa000000bfff /* 0x23 ring 3 3.95GB code at 0x0 */ - .quad 0x00cff2000000bfff /* 0x2b ring 3 3.95GB data at 0x0 */ + .quad 0x00cfba000000c3ff /* 0x11 ring 1 3.95GB code at 0x0 */ + .quad 0x00cfb2000000c3ff /* 0x19 ring 1 3.95GB data at 0x0 */ + .quad 0x00cffa000000c3ff /* 0x23 ring 3 3.95GB code at 0x0 */ + .quad 0x00cff2000000c3ff /* 0x2b ring 3 3.95GB data at 0x0 */ .quad 0x00cf9a000000ffff /* 0x30 ring 0 4.00GB code at 0x0 */ .quad 0x00cf92000000ffff /* 0x38 ring 0 4.00GB data at 0x0 */ .fill NR_CPUS,8,0 /* space for TSS's */ diff --git a/xen-2.4.16/arch/i386/mm.c b/xen-2.4.16/arch/i386/mm.c index 29553a9c9b..2d4d8ddf52 100644 --- a/xen-2.4.16/arch/i386/mm.c +++ b/xen-2.4.16/arch/i386/mm.c @@ -73,8 +73,14 @@ void __init paging_init(void) /* Create page table for ioremap(). */ ioremap_pt = (void *)get_free_page(GFP_KERNEL); clear_page(ioremap_pt); - idle0_pg_table[MAPCACHE_VIRT_START >> L2_PAGETABLE_SHIFT] = + idle0_pg_table[IOREMAP_VIRT_START >> L2_PAGETABLE_SHIFT] = mk_l2_pgentry(__pa(ioremap_pt) | PAGE_HYPERVISOR); + + /* Create read-only mapping of MPT for guest-OS use. */ + idle0_pg_table[READONLY_MPT_VIRT_START >> L2_PAGETABLE_SHIFT] = + idle0_pg_table[RDWR_MPT_VIRT_START >> L2_PAGETABLE_SHIFT]; + mk_l2_readonly(idle0_pg_table + + (READONLY_MPT_VIRT_START >> L2_PAGETABLE_SHIFT)); } void __init zap_low_mappings (void) diff --git a/xen-2.4.16/arch/i386/xeno.lds b/xen-2.4.16/arch/i386/xeno.lds index aff3932ea3..5947ebada5 100644 --- a/xen-2.4.16/arch/i386/xeno.lds +++ b/xen-2.4.16/arch/i386/xeno.lds @@ -6,7 +6,7 @@ OUTPUT_ARCH(i386) ENTRY(start) SECTIONS { - . = 0xFC000000 + 0x100000; + . = 0xFC400000 + 0x100000; _text = .; /* Text and read-only data */ .text : { *(.text) diff --git a/xen-2.4.16/common/domain.c b/xen-2.4.16/common/domain.c index 9608894832..b6279f52fe 100644 --- a/xen-2.4.16/common/domain.c +++ b/xen-2.4.16/common/domain.c @@ -576,6 +576,9 @@ int setup_guestos(struct task_struct *p, dom0_newdomain_t *params) net_ring_t *net_ring; net_vif_t *net_vif; + /* Sanity! */ + if ( p->domain != 0 ) BUG(); + if ( strncmp(__va(mod[0].mod_start), "XenoGues", 8) ) { printk("DOM%d: Invalid guest OS image\n", dom); @@ -622,10 +625,13 @@ int setup_guestos(struct task_struct *p, dom0_newdomain_t *params) memset(l2tab, 0, DOMAIN_ENTRIES_PER_L2_PAGETABLE*sizeof(l2_pgentry_t)); p->mm.pagetable = mk_pagetable(phys_l2tab); + /* Domain 0 gets WRITE access to the read-only machine->physical table. */ + mk_l2_writeable(l2tab + (READONLY_MPT_VIRT_START >> L2_PAGETABLE_SHIFT)); + /* - * NB. The upper limit on this loop does one extra page + pages for frame table. - * This is to make sure a pte exists when we want to map the shared_info struct - * and frame table struct. + * NB. The upper limit on this loop does one extra page + pages for frame + * table. This is to make sure a pte exists when we want to map the + * shared_info struct and frame table struct. */ ft_pages = frame_table_size >> PAGE_SHIFT; diff --git a/xen-2.4.16/common/memory.c b/xen-2.4.16/common/memory.c index ed913e5752..ec11ec6e5d 100644 --- a/xen-2.4.16/common/memory.c +++ b/xen-2.4.16/common/memory.c @@ -224,15 +224,15 @@ void __init init_frametable(unsigned long nr_pages) max_page = nr_pages; frame_table_size = nr_pages * sizeof(struct pfn_info); frame_table_size = (frame_table_size + PAGE_SIZE - 1) & PAGE_MASK; - free_pfns = nr_pages - - ((MAX_MONITOR_ADDRESS + frame_table_size) >> PAGE_SHIFT); - - frame_table = phys_to_virt(MAX_MONITOR_ADDRESS); + frame_table = (frame_table_t *)FRAMETABLE_VIRT_START; memset(frame_table, 0, frame_table_size); + free_pfns = nr_pages - + ((__pa(frame_table) + frame_table_size) >> PAGE_SHIFT); + /* Put all domain-allocatable memory on a free list. */ INIT_LIST_HEAD(&free_list); - for( page_index = (MAX_MONITOR_ADDRESS + frame_table_size) >> PAGE_SHIFT; + for( page_index = (__pa(frame_table) + frame_table_size) >> PAGE_SHIFT; page_index < nr_pages; page_index++ ) { @@ -364,6 +364,12 @@ static int get_l2_table(unsigned long page_nr) DOMAIN_ENTRIES_PER_L2_PAGETABLE] = mk_l2_pgentry(__pa(current->mm.perdomain_pt) | __PAGE_HYPERVISOR); + /* + * DOM0 has the MPT mapped as WRITABLE. + * 'p_l2_entry' happens to be pointing at the right place at this point :-) + */ + if ( current->domain == 0 ) mk_l2_writeable(p_l2_entry); + out: unmap_domain_mem(p_l2_entry); return ret; diff --git a/xen-2.4.16/include/asm-i386/page.h b/xen-2.4.16/include/asm-i386/page.h index b0d68a324a..5b2d1fabc5 100644 --- a/xen-2.4.16/include/asm-i386/page.h +++ b/xen-2.4.16/include/asm-i386/page.h @@ -73,7 +73,7 @@ typedef struct { unsigned long pt_lo; } pagetable_t; #define l1_pgentry_empty(_x) (!l1_pgentry_val(_x)) #define l2_pgentry_empty(_x) (!l2_pgentry_val(_x)) -#define __PAGE_OFFSET (0xFC000000) +#define __PAGE_OFFSET (0xFC400000) #define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET) #define __pa(x) ((unsigned long)(x)-PAGE_OFFSET) #define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET)) @@ -83,7 +83,7 @@ typedef struct { unsigned long pt_lo; } pagetable_t; /* High table entries are reserved by the hypervisor. */ #define DOMAIN_ENTRIES_PER_L2_PAGETABLE \ - (PAGE_OFFSET >> L2_PAGETABLE_SHIFT) + (HYPERVISOR_VIRT_START >> L2_PAGETABLE_SHIFT) #define HYPERVISOR_ENTRIES_PER_L2_PAGETABLE \ (ENTRIES_PER_L2_PAGETABLE - DOMAIN_ENTRIES_PER_L2_PAGETABLE) @@ -153,6 +153,16 @@ __asm__ __volatile__("invlpg %0": :"m" (*(char *) (__addr))) #define PAGE_HYPERVISOR_RO MAKE_GLOBAL(__PAGE_HYPERVISOR_RO) #define PAGE_HYPERVISOR_NOCACHE MAKE_GLOBAL(__PAGE_HYPERVISOR_NOCACHE) +#define mk_l2_writeable(_p) \ + (*(_p) = mk_l2_pgentry(l2_pgentry_val(*(_p)) | _PAGE_RW)) +#define mk_l2_readonly(_p) \ + (*(_p) = mk_l2_pgentry(l2_pgentry_val(*(_p)) & ~_PAGE_RW)) +#define mk_l1_writeable(_p) \ + (*(_p) = mk_l1_pgentry(l1_pgentry_val(*(_p)) | _PAGE_RW)) +#define mk_l1_readonly(_p) \ + (*(_p) = mk_l1_pgentry(l1_pgentry_val(*(_p)) & ~_PAGE_RW)) + + #ifndef __ASSEMBLY__ static __inline__ int get_order(unsigned long size) { diff --git a/xen-2.4.16/include/hypervisor-ifs/hypervisor-if.h b/xen-2.4.16/include/hypervisor-ifs/hypervisor-if.h index 9038d51d11..6052c7b698 100644 --- a/xen-2.4.16/include/hypervisor-ifs/hypervisor-if.h +++ b/xen-2.4.16/include/hypervisor-ifs/hypervisor-if.h @@ -10,7 +10,11 @@ #ifndef __HYPERVISOR_IF_H__ #define __HYPERVISOR_IF_H__ -/* Virtual addresses beyond this are inaccessible by guest OSes. */ +/* + * Virtual addresses beyond this are not modifiable by guest OSes. + * The machine->physical mapping table starts at this address, read-only + * to all domains except DOM0. + */ #define HYPERVISOR_VIRT_START (0xFC000000UL) typedef struct trap_info_st diff --git a/xen-2.4.16/include/xeno/config.h b/xen-2.4.16/include/xeno/config.h index f139a80066..54fcf6f83f 100644 --- a/xen-2.4.16/include/xeno/config.h +++ b/xen-2.4.16/include/xeno/config.h @@ -41,12 +41,33 @@ #define __cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES))) #define ____cacheline_aligned __cacheline_aligned -/* 0-16MB is fixed monitor space. 0-52MB is direct-mapped at top of memory.*/ +/*** Hypervisor owns top 64MB of virtual address space. ***/ +#define HYPERVISOR_VIRT_START (0xFC000000UL) + +/* + * First 4MB are mapped read-only for all. It's for the machine->physical + * mapping table (MPT table). The following are virtual addresses. + */ +#define READONLY_MPT_VIRT_START (HYPERVISOR_VIRT_START) +#define READONLY_MPT_VIRT_END (READONLY_MPT_VIRT_START + (4*1024*1024)) +/* + * Next 16MB is fixed monitor space, which is part of a 48MB direct-mapped + * memory region. The following are machine addresses. + */ #define MAX_MONITOR_ADDRESS (16*1024*1024) #define MAX_DMA_ADDRESS (16*1024*1024) -#define MAX_DIRECTMAP_ADDRESS (52*1024*1024) +#define MAX_DIRECTMAP_ADDRESS (48*1024*1024) +/* And the virtual addresses for the direct-map region... */ +#define DIRECTMAP_VIRT_START (READONLY_MPT_VIRT_END) +#define DIRECTMAP_VIRT_END (DIRECTMAP_VIRT_START + MAX_DIRECTMAP_ADDRESS) +#define MONITOR_VIRT_START (DIRECTMAP_VIRT_START) +#define MONITOR_VIRT_END (MONITOR_VIRT_START + MAX_MONITOR_ADDRESS) +#define RDWR_MPT_VIRT_START (MONITOR_VIRT_END) +#define RDWR_MPT_VIRT_END (RDWR_MPT_VIRT_START + (4*1024*1024)) +#define FRAMETABLE_VIRT_START (RDWR_MPT_VIRT_END) +#define FRAMETABLE_VIRT_END (DIRECTMAP_VIRT_END) /* Next 4MB of virtual address space used for per-domain mappings (eg. GDT). */ -#define PERDOMAIN_VIRT_START (PAGE_OFFSET + MAX_DIRECTMAP_ADDRESS) +#define PERDOMAIN_VIRT_START (DIRECTMAP_VIRT_END) #define PERDOMAIN_VIRT_END (PERDOMAIN_VIRT_START + (4*1024*1024)) /* Penultimate 4MB of virtual address space used for domain page mappings. */ #define MAPCACHE_VIRT_START (PERDOMAIN_VIRT_END) -- 2.30.2